import { IWonewSer } from "@/typing";
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import * as CryptoJs from "crypto-js";
import IHelper from "@/services/helper.service";
import { RedisProvider } from "@/core/providers/redis.provider";
import { create } from "xmlbuilder2";
import { XMLBuilder } from "fast-xml-parser";
import {
  Completions,
  ChatCompletion,
  setEnvVariable,
} from "@baiducloud/qianfan";
import { Observable, defer, map } from "rxjs";
import OpenAI from "openai";

@Injectable()
export class WechatService {
  constructor(
    private readonly configService: ConfigService,
    private readonly redisProvider: RedisProvider,
  ) {}

  getAccessToken() {
    return this.redisProvider.get("access_token");
  }

  auth2(opt: { code: string }) {}

  getAuthUri(redirectUri: string) {
    const scope: "snsapi_userinfo" | "snsapi_base" = "snsapi_userinfo";
    return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.configService.get("WECHAT_APP_ID")}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${scope}&state=${IHelper.hash(8)}#wechat_redirect`;
  }

  verifySign(query: IWonewSer.WechatVerifyParams) {
    const temp = [
      this.configService.get("WECHAT_SERVER_TOKEN"),
      query.timestamp,
      query.nonce,
    ]
      .sort()
      .join("");
    const signature = CryptoJs.SHA1(temp).toString();
    return signature === query.signature ? query.echostr : "failed";
  }

  buildReplayMessage(
    message: IWonewSer.WechatMessage,
    content: string,
  ): IWonewSer.WechatMessage {
    const replayMessage: IWonewSer.WechatMessage = {
      ToUserName: message.FromUserName,
      FromUserName: message.ToUserName,
      CreateTime: IHelper.unix(),
      MsgType: "text",
      Content: message.MsgType !== "text" ? "我现在只能回复文字消息" : content,
      MsgId: IHelper.hash(12),
    };
    return replayMessage;
  }

  buildReply(message: IWonewSer.WechatMessage): Observable<string> {
    return this.getReplay(message.Content).pipe(
      map((result) => this.buildReplayMessage(message, result)),
      map((d) => this.convert2Xml(d)),
    );
  }

  getReplay(content: string): Observable<string> {
    const client = new ChatCompletion({
      QIANFAN_ACCESS_KEY: this.configService.get("QIANFAN_ACCESS_KEY"),
      QIANFAN_SECRET_KEY: this.configService.get("QIANFAN_ACCESS_SECRET_KEY"),
    });
    return defer(() =>
      client.chat({
        messages: [
          {
            role: "user",
            content,
          },
        ],
      }),
    ).pipe(map((res) => res.result || "我无法理解你在说什么..."));
  }

  convert2Xml(message: IWonewSer.WechatMessage): string {
    const xmlJson = {
      ToUserName: `<![CDATA[${message.ToUserName}]]>`, //	接收方帐号（收到的OpenID）
      FromUserName: `<![CDATA[${message.FromUserName}]]>`, //	开发者微信号
      CreateTime: IHelper.unix(), //	消息创建时间 （整型）
      MsgType: `<![CDATA[text]]>`,
      Content: `<![CDATA[${`${message.Content}`}]]>`,
    };
    return new XMLBuilder({ format: false })
      .build({ xml: xmlJson })
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">");
  }

  handleMessage(message: IWonewSer.WechatMessage) {
    // const res = create({
    //   ToUserName: message.FromUserName, //	接收方帐号（收到的OpenID）
    //   FromUserName: message.ToUserName, //	开发者微信号
    //   CreateTime: IHelper.unix(), //	消息创建时间 （整型）
    //   MsgType: 'text',
    //   Content: `replay ${message.Content}`,
    // }).end({ prettyPrint: true })
    const res = new XMLBuilder({ format: true })
      .build({
        xml: {
          ToUserName: `\<![CDATA[${message.FromUserName}]]>`, //	接收方帐号（收到的OpenID）
          FromUserName: `<![CDATA[${message.ToUserName}]]>`, //	开发者微信号
          CreateTime: IHelper.unix(), //	消息创建时间 （整型）
          MsgType: `<![CDATA[text]]>`,
          Content: `<![CDATA[${`replay ${message.Content}`}]]>`,
        },
      })
      .replace(/&lt;/g, "<")
      .replace(/&gt;/g, ">");
    // console.log("ressss312313", res)
    const replayData = `
      <xml>
        <ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
        <FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
        <CreateTime>${IHelper.unix()}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[${`replay ${message.Content}`}]]></Content>
      </xml>
    `;
    var xmlContent =
      "<xml><ToUserName><![CDATA[" + message.FromUserName + "]]></ToUserName>";
    xmlContent +=
      "<FromUserName><![CDATA[" + message.ToUserName + "]]></FromUserName>";
    xmlContent += "<CreateTime>" + new Date().getTime() + "</CreateTime>";
    xmlContent += "<MsgType><![CDATA[text]]></MsgType>";
    xmlContent +=
      "<Content><![CDATA[" + message.Content + " replay]]></Content></xml>";
    console.log("xmlContentxmlContentxmlContent", xmlContent);
    return xmlContent;
  }
}
